home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************/
- /* TARGET.C - Functions related to targets. */
- /***********************************************************************/
- /*
- * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
- * Copyright (C) 1991-1995 Mark Hessling
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to:
- *
- * The Free Software Foundation, Inc.
- * 675 Mass Ave,
- * Cambridge, MA 02139 USA.
- *
- *
- * If you make modifications to this software that you feel increases
- * it usefulness for the rest of the community, please email the
- * changes, enhancements, bug fixes as well as any and all ideas to me.
- * This software is going to be maintained and enhanced as deemed
- * necessary by the community.
- *
- * Mark Hessling email: M.Hessling@gu.edu.au
- * 36 David Road Phone: +61 7 849 7731
- * Holland Park Fax: +61 7 875 5314
- * QLD 4121
- * Australia
- */
-
- /*
- $Id: target.c 2.0 1995/01/26 16:32:04 MH Release MH $
- */
-
- #include <stdio.h>
- #include "the.h"
- #include "proto.h"
-
- #define STATE_START 0
- #define STATE_DELIM 1
- #define STATE_STRING 2
- #define STATE_BOOLEAN 3
- #define STATE_NEXT 4
- #define STATE_POINT 5
- #define STATE_ABSOLUTE 6
- #define STATE_RELATIVE 7
- #define STATE_POSITIVE 8
- #define STATE_NEGATIVE 9
- #define STATE_SPARE 10
- #define STATE_QUIT 98
- #define STATE_ERROR 99
-
- #ifdef PROTO
- static bool is_blank(LINE *);
- #else
- static bool is_blank();
- #endif
-
- /***********************************************************************/
- #ifdef PROTO
- short split_change_params(CHARTYPE *cmd_line,CHARTYPE **old_str,CHARTYPE **new_str,
- TARGET *target,LINETYPE *num,LINETYPE *occ)
- #else
- short split_change_params(cmd_line,old_str,new_str,target,num,occ)
- CHARTYPE *cmd_line,**old_str,**new_str;
- TARGET *target;
- LINETYPE *num,*occ;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- #define SCP_PARAMS 2
- CHARTYPE *word[SCP_PARAMS+1];
- register short i=0,j=0;
- CHARTYPE *target_start=NULL;
- short rc=RC_OK;
- CHARTYPE delim=' ';
- short idx=0;
- short target_type = TARGET_NORMAL|TARGET_BLOCK_CURRENT|TARGET_ALL|TARGET_SPARE;
- unsigned short num_params=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: split_change_params");
- #endif
- /*---------------------------------------------------------------------*/
- /* First, determine the delimiter; the first character in the argument */
- /* string. */
- /*---------------------------------------------------------------------*/
- delim = *(cmd_line);
- /*---------------------------------------------------------------------*/
- /* Set up default values for the return values... */
- /*---------------------------------------------------------------------*/
- *old_str = cmd_line+1;
- *new_str = (CHARTYPE *)"";
- target_start = (CHARTYPE *)"";
- *num = *occ = 1L;
- target->num_lines = 1L;
- target->true_line = get_true_line();
- /*---------------------------------------------------------------------*/
- /* Set up default values for the return values... */
- /*---------------------------------------------------------------------*/
- idx = strlen(cmd_line);
- for (i=1,j=0;i<idx;i++)
- {
- if (*(cmd_line+i) == delim)
- {
- j++;
- switch(j)
- {
- case 1:
- *(cmd_line+i) = '\0';
- *new_str = cmd_line+i+1;
- break;
- case 2:
- *(cmd_line+i) = '\0';
- target_start = cmd_line+i+1;
- break;
- default:
- break;
- }
- }
- if (j == 2)
- break;
- }
- /*---------------------------------------------------------------------*/
- /* Check to see if there is a target, if not return here. */
- /*---------------------------------------------------------------------*/
- if (blank_field(target_start))
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /*---------------------------------------------------------------------*/
- /* Parse and validate the target... */
- /*---------------------------------------------------------------------*/
- if ((rc = validate_target(target_start,target,target_type,get_true_line(),TRUE,TRUE)) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /*---------------------------------------------------------------------*/
- /* Check to see if there are further arguments after the target... */
- /*---------------------------------------------------------------------*/
- if (target->spare == (-1))
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /*---------------------------------------------------------------------*/
- /* Validate the arguments following the target... */
- /*---------------------------------------------------------------------*/
- num_params = param_split(strtrunc(target->rt[target->spare].string),word,SCP_PARAMS,WORD_DELIMS,TEMP_PARAM);
- if (num_params == 1
- || num_params == 2)
- {
- if (strcmp(word[0],"*") == 0)
- *num = MAX_LONG;
- else
- if (!valid_positive_integer(word[0]))
- {
- display_error(4,word[0],FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_INVALID_OPERAND);
- }
- else
- *num = atol(word[0]);
- }
- if (num_params == 2)
- {
- if (!valid_positive_integer(word[1]))
- {
- display_error(4,word[1],FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_INVALID_OPERAND);
- }
- else
- *occ = atol(word[1]);
- }
-
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- short parse_target(CHARTYPE *target_spec,LINETYPE true_line,
- TARGET *target,short target_types,bool display_parse_error,
- bool allow_error_display)
- #else
- short parse_target(target_spec,true_line,target,target_types,display_parse_error,allow_error_display)
- CHARTYPE *target_spec;
- LINETYPE true_line;
- TARGET *target;
- short target_types;
- bool display_parse_error,allow_error_display;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- short num_targets=0;
- CHARTYPE boolean=' ';
- short state=STATE_NEXT;
- short len=0,inc=0,target_length=strlen(target_spec),off=0;
- CHARTYPE delim=' ';
- register short i=0;
- register short j=0;
- short str_start=0,str_end=0;
- short rtarget=0,rc=RC_OK;
- short potential_spare_start=0;
- bool negative=FALSE;
- CHARTYPE *ptr=NULL;
- LINETYPE lineno=0L;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: parse_target");
- #endif
- /*---------------------------------------------------------------------*/
- /* Copy the incoming target specification... */
- /*---------------------------------------------------------------------*/
- if ((target->string = (CHARTYPE *)my_strdup(target_spec)) == NULL)
- {
- if (allow_error_display)
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- ptr = target->string;
- /*---------------------------------------------------------------------*/
- /* Parse the target... */
- /*---------------------------------------------------------------------*/
- while(1)
- {
- inc = 1;
- switch(state)
- {
- case STATE_NEXT:
- if (target->rt == NULL)
- target->rt = (RTARGET *)(*the_malloc)((num_targets+1)*sizeof(RTARGET));
- else
- target->rt = (RTARGET *)(*the_realloc)(target->rt,(num_targets+1)*sizeof(RTARGET));
- if (target->rt == NULL)
- {
- if (allow_error_display)
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- target->rt[num_targets].not = FALSE;
- target->rt[num_targets].boolean = boolean;
- target->rt[num_targets].length = 0;
- target->rt[num_targets].string = NULL;
- target->rt[num_targets].negative = FALSE;
- target->rt[num_targets].target_type = TARGET_ERR;
- if (target->spare != (-1))
- state = STATE_SPARE;
- else
- state = STATE_START;
- inc = 0;
- break;
- case STATE_START:
- switch(*(ptr+i))
- {
- case '~': case '^':
- if (target->rt[num_targets].not)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- target->rt[num_targets].not = TRUE;
- break;
- case ' ':
- case '\t':
- break;
- case '-':
- if (target->rt[num_targets].negative)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- target->rt[num_targets].negative = TRUE;
- state = STATE_NEGATIVE;
- break;
- case '+':
- if (target->rt[num_targets].negative)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- inc = 1;
- break;
- case '.':
- if (target->rt[num_targets].negative)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- state = STATE_POINT;
- str_start = i;
- break;
- case '*':
- state = STATE_BOOLEAN;
- target->rt[num_targets].target_type = TARGET_RELATIVE;
- target->rt[num_targets].string = (CHARTYPE *)(*the_malloc)(3);
- if (target->rt[num_targets].string == NULL)
- {
- if (allow_error_display)
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- if (target->rt[num_targets].negative)
- {
- target->rt[num_targets].numeric_target = true_line*(-1L);
- strcpy(target->rt[num_targets].string,"-*");
- }
- else
- {
- target->rt[num_targets].numeric_target = (CURRENT_FILE->number_lines - true_line) + 2;
- strcpy(target->rt[num_targets].string,"*");
- }
- inc = 1;
- potential_spare_start = i+1;
- num_targets++;
- break;
- case ':': case ';':
- state = STATE_ABSOLUTE;
- delim = *(ptr+i);
- str_start = i+1;
- break;
- case '/': case '\\': case '@':
- state = STATE_STRING;
- str_start = i+1;
- delim = *(ptr+i);
- break;
- case 'a': case 'A':
- if (target->rt[num_targets].not
- || target->rt[num_targets].negative)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- if (target_length-i < 3)
- {
- target->rt[num_targets].target_type = TARGET_ERR;
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- if (memcmpi("all",ptr+i,3) == 0
- && (*(ptr+(i+3)) == ' '
- || *(ptr+(i+3)) == '\0'
- || *(ptr+(i+3)) == '\t'))
- {
- target->rt[num_targets].target_type = TARGET_ALL;
- inc = 3;
- state = STATE_BOOLEAN;
- num_targets++;
- potential_spare_start = i+3;
- break;
- }
- state = STATE_ERROR;
- inc = 0;
- break;
- case 'b': case 'B':
- if (target_length-i < 5)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- if (memcmpi("blank",ptr+i,5) == 0
- && (*(ptr+(i+5)) == ' '
- || *(ptr+(i+5)) == '\0'
- || *(ptr+(i+5)) == '\t'))
- {
- target->rt[num_targets].target_type = TARGET_BLANK;
- inc = 5;
- potential_spare_start = i+5;
- state = STATE_BOOLEAN;
- num_targets++;
- break;
- }
- if (target->rt[num_targets].not
- || target->rt[num_targets].negative)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- if (memcmpi("block",ptr+i,5) == 0
- && (*(ptr+(i+5)) == ' '
- || *(ptr+(i+5)) == '\0'
- || *(ptr+(i+5)) == '\t'))
- {
- target->rt[num_targets].target_type = TARGET_BLOCK;
- inc = 5;
- potential_spare_start = i+5;
- state = STATE_BOOLEAN;
- num_targets++;
- break;
- }
- state = STATE_ERROR;
- inc = 0;
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- state = STATE_RELATIVE;
- str_start = i;
- delim = '\0';
- inc = 0;
- break;
- default:
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- break;
- case STATE_STRING:
- switch(*(ptr+i))
- {
- case '/': case '\\': case '@':
- case '\0':
- if (*(ptr+i) == delim
- || *(ptr+i) == '\0')
- {
- state = STATE_BOOLEAN;
- str_end = i;
- len = str_end-str_start;
- target->rt[num_targets].string = (CHARTYPE *)(*the_malloc)(len+1);
- if (target->rt[num_targets].string == NULL)
- {
- if (allow_error_display)
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- memcpy(target->rt[num_targets].string,ptr+str_start,len);
- target->rt[num_targets].string[len] = '\0';
- target->rt[num_targets].length = len;
- target->rt[num_targets].target_type = TARGET_STRING;
- potential_spare_start = i+1;
- num_targets++;
- }
- break;
- default:
- break;
- }
- break;
- case STATE_BOOLEAN:
- switch(*(ptr+i))
- {
- case '\0':
- break;
- case ' ':
- case '\t':
- break;
- case '&':
- case '|':
- state = STATE_NEXT;
- boolean = *(ptr+i);
- break;
- default:
- if (target_types & TARGET_SPARE)
- {
- /* str_start = i;*/
- str_start = potential_spare_start;
- state = STATE_NEXT;
- target->spare = 0; /* just to ensure state is set */
- break;
- }
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- break;
- case STATE_SPARE:
- switch(*(ptr+i))
- {
- case '\0':
- str_end = i;
- len = str_end-str_start;
- target->rt[num_targets].string = (CHARTYPE *)(*the_malloc)(len+1);
- if (target->rt[num_targets].string == NULL)
- {
- if (allow_error_display)
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- memcpy(target->rt[num_targets].string,ptr+str_start,len);
- target->rt[num_targets].string[len] = '\0';
- target->rt[num_targets].length = len;
- target->rt[num_targets].target_type = TARGET_SPARE;
- target->spare = num_targets;
- num_targets++;
- *(ptr+str_start) = '\0'; /* so target string does not include spare */
- break;
- default:
- break;
- }
- break;
- case STATE_ABSOLUTE:
- case STATE_RELATIVE:
- if (target->rt[num_targets].not)
- {
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- switch(*(ptr+i))
- {
- case '\0':
- case ' ':
- case '\t':
- str_end = i;
- len = str_end-str_start;
- target->rt[num_targets].string = (CHARTYPE *)(*the_malloc)(len+2);
- if (target->rt[num_targets].string == NULL)
- {
- if (allow_error_display)
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- if (delim != '\0')
- {
- target->rt[num_targets].string[0] = delim;
- off = 1;
- }
- else
- off = 0;
- memcpy(target->rt[num_targets].string+off,ptr+str_start,len);
- target->rt[num_targets].string[len+off] = '\0';
- target->rt[num_targets].length = len+off;
- target->rt[num_targets].target_type = (state == STATE_ABSOLUTE) ? TARGET_ABSOLUTE : TARGET_RELATIVE;
- target->rt[num_targets].numeric_target = atol(target->rt[num_targets].string+off);
- if (target->rt[num_targets].negative)
- target->rt[num_targets].numeric_target *= (-1L);
- if (state == STATE_ABSOLUTE)
- {
- if (target->rt[num_targets].numeric_target < true_line)
- target->rt[num_targets].negative = TRUE;
- else
- target->rt[num_targets].numeric_target = min(target->rt[num_targets].numeric_target,(CURRENT_FILE->number_lines+1L));
- }
- else
- {
- if (target->rt[num_targets].negative)
- target->rt[num_targets].numeric_target = max((target->rt[num_targets].numeric_target),(true_line == 0L) ? (0L) : (true_line*(-1L)));
- else
- target->rt[num_targets].numeric_target = min(target->rt[num_targets].numeric_target,(CURRENT_FILE->number_lines - true_line+1L));
- }
- potential_spare_start = i;
- num_targets++;
- state = STATE_BOOLEAN;
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- break;
- default:
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- break;
- case STATE_NEGATIVE:
- switch(*(ptr+i))
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- state = STATE_RELATIVE;
- delim = '-';
- str_start = i;
- inc = 0;
- break;
- case '/': case '\\': case '@':
- state = STATE_START;
- inc = 0;
- break;
- case '*':
- state = STATE_START;
- inc = 0;
- break;
- case 'b': case 'B':
- state = STATE_START;
- inc = 0;
- break;
- default:
- state = STATE_ERROR;
- inc = 0;
- break;
- }
- break;
- case STATE_POINT:
- switch(*(ptr+i))
- {
- case ' ':
- case '\t':
- state = STATE_BOOLEAN;
- /* fall through */
- case '&':
- case '|':
- case '\0':
- target->rt[num_targets].target_type = TARGET_POINT;
- str_end = i;
- len = str_end-str_start;
- target->rt[num_targets].string = (CHARTYPE *)(*the_malloc)(len+1);
- if (target->rt[num_targets].string == NULL)
- {
- if (allow_error_display)
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- memcpy(target->rt[num_targets].string,ptr+str_start,len);
- target->rt[num_targets].string[len] = '\0';
- target->rt[num_targets].length = len;
- if (find_named_line(target->rt[num_targets].string,&lineno,TRUE) == NULL)
- {
- state = STATE_ERROR;
- break;
- }
- target->rt[num_targets].numeric_target = lineno;
- if (target->rt[num_targets].numeric_target < true_line)
- target->rt[num_targets].negative = TRUE;
- else
- target->rt[num_targets].numeric_target = min(target->rt[num_targets].numeric_target,(CURRENT_FILE->number_lines+1L));
- num_targets++;
- potential_spare_start = i;
- if (*(ptr+i) == ' ' || *(ptr+i) == '\t')
- break;
- boolean = *(ptr+i);
- state = STATE_NEXT;
- break;
- default:
- break;
- }
- break;
- case STATE_ERROR:
- for (j=0;j<num_targets;j++)
- target->rt[j].target_type = TARGET_ERR;
- state = STATE_QUIT;
- break;
- }
- if (state == STATE_QUIT)
- break;
- i += inc;
- if (i > target_length) /* this allows for testing '\0' as delimiter */
- break;
- }
- target->num_targets = num_targets;
- if (num_targets == 0
- || target->rt[0].target_type == TARGET_ERR)
- {
- if (display_parse_error
- && allow_error_display)
- display_error(1,ptr,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_INVALID_OPERAND);
- }
- /*---------------------------------------------------------------------*/
- /* Time to validate the targets we have parsed... */
- /*---------------------------------------------------------------------*/
- /* Valid combinations are: */
- /* TARGET_ALL (1 target only) */
- /* ALL only */
- /* TARGET_BLOCK (1 target only) */
- /* BLOCK only */
- /* this section sets target_type to TARGET_BLOCK_ANY */
- /* or TARGET_BLOCK_CURRENT */
- /* TARGET_BLANK (BLANK can be upper or lower case) */
- /* BLANK */
- /* -BLANK */
- /* ~BLANK */
- /* ~-BLANK */
- /* TARGET_STRING (valid delimiters are / \ or @ */
- /* /string/ */
- /* -/string/ */
- /* ~/string/ */
- /* ~-/string/ */
- /* TARGET_POINT */
- /* .xxxxxx */
- /* ~.xxxxxx */
- /* TARGET_ABSOLUTE */
- /* :99 */
- /* ;99 */
- /* TARGET_RELATIVE */
- /* 99 */
- /* +99 */
- /* -99 */
- /* * */
- /* +* */
- /* -* */
- /* */
- /* Any of the above target types may be or'd together. */
- /*---------------------------------------------------------------------*/
- /*---------------------------------------------------------------------*/
- /* For each of the targets, check its validity... */
- /*---------------------------------------------------------------------*/
- negative = target->rt[0].negative;
- for (i=0;i<num_targets-((target->spare == (-1)) ? 0 : 1);i++)
- {
- switch(target->rt[i].target_type)
- {
- case TARGET_BLOCK:
- if (num_targets-((target->spare == (-1)) ? 0 : 1) != 1)
- {
- rc = RC_INVALID_OPERAND;
- break;
- }
- if (target_types & TARGET_BLOCK_ANY)
- target->rt[i].target_type = TARGET_BLOCK_ANY;
- else
- if (target_types & TARGET_BLOCK_CURRENT)
- target->rt[i].target_type = TARGET_BLOCK_CURRENT;
- else
- rc = RC_INVALID_OPERAND;
- break;
- case TARGET_ALL:
- if (num_targets-((target->spare == (-1)) ? 0 : 1) != 1)
- {
- rc = RC_INVALID_OPERAND;
- break;
- }
- if (target_types & target->rt[i].target_type)
- break;
- rc = RC_INVALID_OPERAND;
- break;
- default:
- if (target->rt[i].negative != negative)
- {
- rc = RC_INVALID_OPERAND;
- break;
- }
- if (target_types & target->rt[i].target_type)
- break;
- rc = RC_INVALID_OPERAND;
- break;
- }
- if (rc == RC_INVALID_OPERAND)
- break;
- }
- /*---------------------------------------------------------------------*/
- /* Display an error if anything found amiss and we are directed to */
- /* display an error... */
- /*---------------------------------------------------------------------*/
- if (rc != RC_OK
- && display_parse_error
- && allow_error_display)
- display_error(1,ptr,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- void initialise_target(TARGET *target)
- #else
- void initialise_target(target)
- TARGET *target;
- #endif
- /***********************************************************************/
- {
- /*--------------------------- local data ------------------------------*/
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: initialise_target");
- #endif
- target->rt=NULL;
- target->string=NULL;
- target->num_lines = target->true_line = 0L;
- target->num_targets = 0;
- target->spare = (-1);
- target->ignore_scope = FALSE;
- #ifdef TRACE
- trace_return();
- #endif
- return;
- }
- /***********************************************************************/
- #ifdef PROTO
- void free_target(TARGET *target)
- #else
- void free_target(target)
- TARGET *target;
- #endif
- /***********************************************************************/
- {
- /*--------------------------- local data ------------------------------*/
- register short i=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: free_target");
- #endif
- if (target->string == NULL
- && target->num_targets == 0
- && target->rt == NULL)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return;
- }
- for (i=0;i<target->num_targets;i++)
- {
- if (target->rt[i].string != NULL)
- (*the_free)(target->rt[i].string);
- }
- if (target->string != NULL)
- (*the_free)(target->string);
- if (target->rt != NULL)
- (*the_free)(target->rt);
- #ifdef TRACE
- trace_return();
- #endif
- return;
- }
- /***********************************************************************/
- #ifdef PROTO
- short find_target(TARGET *target,LINETYPE true_line,bool display_parse_error,bool allow_error_display)
- #else
- short find_target(target,true_line,display_parse_error,allow_error_display)
- TARGET *target;
- LINETYPE true_line;
- bool display_parse_error,allow_error_display;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern bool in_profile;
- extern VIEW_DETAILS *vd_mark;
- /*--------------------------- local data ------------------------------*/
- short rc=RC_OK;
- LINE *curr=NULL;
- LINETYPE num_lines=0L;
- LINETYPE line_number=0L;
- bool status=FALSE;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_target");
- #endif
- /*---------------------------------------------------------------------*/
- /* Check single targets first (ALL and BLOCK) */
- /*---------------------------------------------------------------------*/
- /*---------------------------------------------------------------------*/
- /* Check if first, and only target, is BLOCK... */
- /*---------------------------------------------------------------------*/
- switch(target->rt[0].target_type)
- {
- case TARGET_ALL:
- target->true_line = 1L;
- target->num_lines = CURRENT_FILE->number_lines;
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- break;
- case TARGET_BLOCK_ANY:
- if (MARK_VIEW == NULL)
- {
- if (allow_error_display)
- display_error(44,"",FALSE);
- rc = RC_TARGET_NOT_FOUND;
- }
- else
- {
- target->num_lines = MARK_VIEW->mark_end_line - MARK_VIEW->mark_start_line + 1L;
- target->true_line = MARK_VIEW->mark_start_line;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- break;
- case TARGET_BLOCK_CURRENT:
- if (MARK_VIEW == NULL)
- {
- if (allow_error_display)
- display_error(44,"",FALSE);
- rc = RC_TARGET_NOT_FOUND;
- }
- else
- {
- if (MARK_VIEW != CURRENT_VIEW)
- {
- if (allow_error_display)
- display_error(45,"",FALSE);
- rc = RC_TARGET_NOT_FOUND;
- }
- else
- {
- target->num_lines = MARK_VIEW->mark_end_line - MARK_VIEW->mark_start_line + 1L;
- target->true_line = MARK_VIEW->mark_start_line;
- }
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- break;
- default:
- break;
- }
- /*---------------------------------------------------------------------*/
- /* All other targets are potentially repeating targets... */
- /*---------------------------------------------------------------------*/
- rc = RC_TARGET_NOT_FOUND;
- status = FALSE;
- line_number = true_line;
- curr = lll_find(CURRENT_FILE->first_line,true_line);
- num_lines = 0L;
- while(1)
- {
- status = find_rtarget_target(curr,target,true_line,line_number,&num_lines);
- if (status)
- break;
- /*---------------------------------------------------------------------*/
- /* We can determine the direction of execution based on the first */
- /* target, as all targets must have the same direction to have reached */
- /* here. */
- /*---------------------------------------------------------------------*/
- if (target->rt[0].negative)
- {
- curr = curr->prev;
- line_number--;
- }
- else
- {
- curr = curr->next;
- line_number++;
- }
- if (curr == NULL)
- break;
- }
- if (status)
- {
- num_lines = ((target->rt[0].negative) ? -num_lines : num_lines);
- target->num_lines = num_lines;
- target->true_line = true_line;
- rc = RC_OK;
- }
- else
- {
- if (allow_error_display)
- display_error(17,target->string,FALSE);
- rc = RC_TARGET_NOT_FOUND;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- static bool is_blank(LINE *curr)
- #else
- static bool is_blank(curr)
- LINE *curr;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- register short i=0;
- bool rc=TRUE;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: is_blank");
- #endif
- if (CURRENT_VIEW->zone_start > curr->length)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(TRUE);
- }
- for (i=CURRENT_VIEW->zone_start-1;i<min(CURRENT_VIEW->zone_end,curr->length);i++)
- {
- if (*(curr->line+i) != ' ')
- {
- rc = FALSE;
- break;
- }
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- LINE *find_named_line(CHARTYPE *name,LINETYPE *retline,bool respect_scope)
- #else
- LINE *find_named_line(name,retline,respect_scope)
- CHARTYPE *name;
- LINETYPE *retline;
- bool respect_scope;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- LINETYPE lineno=0;
- LINE *curr=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_named_line");
- #endif
- /*---------------------------------------------------------------------*/
- /* Find the line number in the current file of the named line specified*/
- /*---------------------------------------------------------------------*/
- curr = CURRENT_FILE->first_line;
- while(curr->next != (LINE *)NULL)
- {
- /*---------------------------------------------------------------------*/
- /* Check the line's name if we are not respecting scope or if we are */
- /* respecting scope and the line is in scope. */
- /*---------------------------------------------------------------------*/
- if (!respect_scope
- || (respect_scope && (in_scope(curr) || CURRENT_VIEW->scope_all)))
- {
- if (curr->name != (CHARTYPE *)NULL)
- if (strcmp(curr->name,name) == 0)
- {
- #ifdef TRACE
- trace_return();
- #endif
- *retline = lineno;
- return(curr);
- }
- }
- lineno++;
- curr = curr->next;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return((LINE *)NULL);
- }
- /***********************************************************************/
- #ifdef PROTO
- short find_string_target(LINE *curr,RTARGET *rt)
- #else
- short find_string_target(curr,rt)
- LINE *curr;
- RTARGET *rt;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE *rec;
- /*--------------------------- local data ------------------------------*/
- CHARTYPE *needle=(CHARTYPE *)rt->string;
- CHARTYPE *haystack=curr->line;
- LENGTHTYPE needle_length=0,haystack_length=0,real_start=0,real_end=0;
- bool use_rec=FALSE;
- short rc=RC_OK;
- short loc=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_string_target");
- #endif
- /*---------------------------------------------------------------------*/
- /* Copy contents of rec into linked to ensure that changes made are */
- /* included in the linked list searched. */
- /*---------------------------------------------------------------------*/
- post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
- /*---------------------------------------------------------------------*/
- /* If HEX is on, convert the target from a HEX format to CHARTYPE. */
- /*---------------------------------------------------------------------*/
- if (CURRENT_VIEW->hex == TRUE)
- {
- rc = convert_hex_strings(needle);
- if (rc == (-1))
- {
- display_error(32,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_INVALID_OPERAND);
- }
- else
- needle_length = rc;
- }
- else
- needle_length = strlen(needle);
- /*---------------------------------------------------------------------*/
- /* Determine if we need to copy the contents of the line into rec. */
- /* The reasons we need to do this are: */
- /* - the length of the needle is 0 */
- /* - the last character of needle is a space */
- /*---------------------------------------------------------------------*/
- if (needle_length == 0)
- use_rec = TRUE;
- else
- if (*(needle+(needle_length-1)) == ' ')
- use_rec = TRUE;
-
- if (use_rec)
- {
- memset(rec,' ',max_line_length);
- memcpy(rec,curr->line,curr->length);
- haystack = rec;
- haystack_length = max_line_length;
- }
- else
- {
- haystack = curr->line;
- haystack_length = curr->length;
- }
- /*---------------------------------------------------------------------*/
- /* Calculate the bounds to search in based on length of haystack and */
- /* ZONE settings. */
- /*---------------------------------------------------------------------*/
- real_end = min(haystack_length,CURRENT_VIEW->zone_end-1);
- real_start = max(0,CURRENT_VIEW->zone_start-1);
- /*---------------------------------------------------------------------*/
- /* Find the needle in the haystack. */
- /*---------------------------------------------------------------------*/
- loc = memfind(haystack+real_start,needle,(real_end-real_start+1),
- needle_length,(CURRENT_VIEW->case_locate == CASE_IGNORE) ? TRUE : FALSE,
- CURRENT_VIEW->arbchar_status,
- CURRENT_VIEW->arbchar_single,
- CURRENT_VIEW->arbchar_multiple);
- if (loc == (-1))
- rc = RC_TARGET_NOT_FOUND;
- else
- rc = RC_OK;
- /*---------------------------------------------------------------------*/
- /* Copy contents of linked list into rec if we have used rec as a work */
- /* area. */
- /*---------------------------------------------------------------------*/
- if (use_rec)
- pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- bool find_rtarget_target(LINE *curr,TARGET *target,LINETYPE true_line,LINETYPE line_number,LINETYPE *num_lines)
- #else
- bool find_rtarget_target(curr,target,true_line,line_number,num_lines)
- LINE *curr;
- TARGET *target;
- LINETYPE true_line,line_number;
- LINETYPE *num_lines;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- register short i=0;
- bool target_found=FALSE,status=FALSE;
- LINETYPE multiplier=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_rtarget_target");
- #endif
- /*---------------------------------------------------------------------*/
- /* If the line is not in scope and scope is respected, return FALSE. */
- /*---------------------------------------------------------------------*/
- if (!(in_scope(curr))
- && !target->ignore_scope)
- {
- if (!CURRENT_VIEW->scope_all
- && !TOF(line_number)
- && !BOF(line_number))
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(FALSE);
- }
- }
- if (line_number != true_line)
- *num_lines = *num_lines + 1L;
- for (i=0;i<target->num_targets-((target->spare == (-1)) ? 0 : 1);i++)
- {
- target_found = FALSE;
- multiplier = (target->rt[i].negative) ? -1L : 1L;
- switch(target->rt[i].target_type)
- {
- case TARGET_BLANK:
- if (true_line == line_number)
- {
- target_found = ((target->rt[i].not) ? TRUE : FALSE);
- break;
- }
- if (target->rt[0].negative)
- {
- if (curr->prev == NULL)
- break;
- }
- else
- {
- if (curr->next == NULL)
- break;
- }
- target_found = is_blank(curr);
- break;
- case TARGET_POINT:
- if (true_line == line_number)
- {
- target_found = ((target->rt[i].not) ? TRUE : FALSE);
- break;
- }
- if (curr->name == (CHARTYPE *)NULL)
- break;
- if (strcmp(curr->name,target->rt[i].string) == 0)
- target_found = TRUE;
- break;
- case TARGET_STRING:
- if (true_line == line_number)
- {
- target_found = ((target->rt[i].not) ? TRUE : FALSE);
- break;
- }
- if (target->rt[0].negative)
- {
- if (curr->prev == NULL)
- break;
- }
- else
- {
- if (curr->next == NULL)
- break;
- }
- if (find_string_target(curr,&target->rt[i]) == RC_OK)
- target_found = TRUE;
- break;
- case TARGET_RELATIVE:
- if ((*num_lines * multiplier) == target->rt[i].numeric_target)
- target_found = TRUE;
- if (target->rt[0].negative)
- {
- if (curr->prev == NULL)
- {
- target_found = TRUE;
- break;
- }
- }
- else
- {
- if (curr->next == NULL)
- {
- target_found = TRUE;
- break;
- }
- }
- break;
- case TARGET_ABSOLUTE:
- if (line_number == target->rt[i].numeric_target)
- target_found = TRUE;
- break;
- default:
- break;
- }
- if (target->rt[i].not)
- target_found = (target_found) ? FALSE : TRUE;
- switch(target->rt[i].boolean)
- {
- case ' ':
- status = target_found;
- break;
- case '&':
- status &= target_found;
- break;
- case '|':
- status |= target_found;
- break;
- }
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(status);
- }
- /***********************************************************************/
- #ifdef PROTO
- LINETYPE find_next_in_scope(LINE *in_curr,LINETYPE line_number,short direction)
- #else
- LINETYPE find_next_in_scope(in_curr,line_number,direction)
- LINE *in_curr;
- LINETYPE line_number;
- short direction;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- LINE *curr=in_curr;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_next_in_scope");
- #endif
- if (in_curr == NULL)
- curr = lll_find(CURRENT_FILE->first_line,line_number);
- for (;;line_number+=(LINETYPE)direction)
- {
- if (in_scope(curr))
- break;
- if (direction == DIRECTION_FORWARD)
- curr = curr->next;
- else
- curr = curr->prev;
- if (curr == NULL)
- break;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(line_number);
- }
- /***********************************************************************/
- #ifdef PROTO
- LINETYPE find_last_not_in_scope(LINE *in_curr,LINETYPE line_number,short direction)
- #else
- LINETYPE find_last_not_in_scope(in_curr,line_number,direction)
- LINE *in_curr;
- LINETYPE line_number;
- short direction;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- LINE *curr=in_curr;
- LINETYPE offset=0L;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_last_not_in_scope");
- #endif
- if (in_curr == NULL)
- curr = lll_find(CURRENT_FILE->first_line,line_number);
- for (;;line_number+=(LINETYPE)direction)
- {
- if (in_scope(curr))
- break;
- if (direction == DIRECTION_FORWARD)
- {
- curr = curr->next;
- offset = (-1L);
- }
- else
- {
- curr = curr->prev;
- offset = 1L;
- }
- if (curr == NULL)
- break;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(line_number+offset);
- }
- /***********************************************************************/
- #ifdef PROTO
- short validate_target(CHARTYPE *string,TARGET *target,short target_type,LINETYPE true_line,bool display_parse_error,bool allow_error_display)
- #else
- short validate_target(string,target,target_type,true_line,display_parse_error,allow_error_display)
- CHARTYPE *string;
- TARGET *target;
- short target_type;
- LINETYPE true_line;
- bool display_parse_error,allow_error_display;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- short rc=RC_OK;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: validate_target");
- #endif
- rc = parse_target(string,true_line,target,target_type,display_parse_error,allow_error_display);
- if (rc != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_INVALID_OPERAND);
- }
- rc = find_target(target,true_line,display_parse_error,allow_error_display);
- if (rc != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_TARGET_NOT_FOUND);
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- bool in_scope(LINE *curr)
- #else
- bool in_scope(curr)
- LINE *curr;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- /*--------------------------- local data ------------------------------*/
- bool rc=RC_OK;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: in_scope");
- #endif
- if (curr->select < CURRENT_VIEW->display_low
- || curr->select > CURRENT_VIEW->display_high)
- rc = FALSE;
- else
- rc = TRUE;
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- void calculate_scroll_values(short *number_focus_rows,LINETYPE *new_focus_line,
- LINETYPE *new_current_line,bool *limit_of_screen,
- bool *limit_of_file,bool *leave_cursor,
- short direction)
- #else
- void calculate_scroll_values(number_focus_rows,new_focus_line,new_current_line,
- limit_of_screen,limit_of_file,leave_cursor,direction)
- short *number_focus_rows;
- LINETYPE *new_focus_line,*new_current_line;
- bool *limit_of_screen,*limit_of_file,*leave_cursor;
- short direction;
- #endif
- /***********************************************************************/
- {
- /*------------------------- external data -----------------------------*/
- /*--------------------------- local data ------------------------------*/
- register short i=0;
- unsigned short x=0,y=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: calculate_scroll_values");
- #endif
- /* getyx(CURRENT_WINDOW,y,x);*/
- *limit_of_screen = *limit_of_file = FALSE;
- *number_focus_rows = 0;
- *new_focus_line = (-1L);
- y = CURRENT_SCREEN.rows[WINDOW_MAIN];
- switch(direction)
- {
- case DIRECTION_FORWARD:
- /*---------------------------------------------------------------------*/
- /* Determine the new focus line and the number of rows to adjust the */
- /* cursor position. */
- /*---------------------------------------------------------------------*/
- for (i=0;i<CURRENT_SCREEN.rows[WINDOW_MAIN];i++)
- {
- if (CURRENT_SCREEN.sl[i].line_number == CURRENT_VIEW->focus_line)
- {
- y = i;
- continue;
- }
- if (CURRENT_SCREEN.sl[i].line_number != (-1L)
- && y != CURRENT_SCREEN.rows[WINDOW_MAIN])
- {
- *number_focus_rows = i-y;
- *new_focus_line = CURRENT_SCREEN.sl[i].line_number;
- break;
- }
- }
- /*---------------------------------------------------------------------*/
- /* If we have NOT set a new focus line (because we are on the bottom */
- /* of the screen) the new focus line is the next line in scope (if */
- /* SHADOW is OFF). If SHADOW is ON, the new focus line is determined by*/
- /* the status of the current focus line. */
- /*---------------------------------------------------------------------*/
- if (*new_focus_line == (-1L))
- {
- if (CURRENT_VIEW->shadow)
- {
- *new_focus_line = CURRENT_SCREEN.sl[y].line_number +
- ((CURRENT_SCREEN.sl[y].number_lines_excluded == 0) ?
- 1L :
- (LINETYPE)CURRENT_SCREEN.sl[y].number_lines_excluded);
- }
- else
- {
- if (CURRENT_SCREEN.sl[y].current->next != NULL)
- *new_focus_line = find_next_in_scope(CURRENT_SCREEN.sl[y].current->next,
- CURRENT_SCREEN.sl[y].line_number+1L,direction);
- }
- }
- /*---------------------------------------------------------------------*/
- /* Determine the new current line and the number of rows to adjust the */
- /* cursor position. */
- /*---------------------------------------------------------------------*/
- *leave_cursor = TRUE;
- *new_current_line = (-1L);
- for (i=CURRENT_VIEW->current_row+1;i<CURRENT_SCREEN.rows[WINDOW_MAIN];i++)
- {
- if (CURRENT_SCREEN.sl[i].line_type == LINE_LINE
- || CURRENT_SCREEN.sl[i].line_type == LINE_TOF_EOF)
- {
- *new_current_line = CURRENT_SCREEN.sl[i].line_number;
- break;
- }
- if (CURRENT_SCREEN.sl[i].line_type == LINE_SHADOW)
- *leave_cursor = FALSE;
- }
- /*---------------------------------------------------------------------*/
- /* If we have NOT set a new current line (only way this can happen is */
- /* if all lines after the current line are RESERVED, SCALE or TABLINE) */
- /* and the cursor is on the current line) the new current line is the */
- /* next line in scope. */
- /*---------------------------------------------------------------------*/
- if (*new_current_line == (-1L))
- {
- if (CURRENT_SCREEN.sl[y].current->next != NULL)
- *new_current_line = find_next_in_scope(CURRENT_SCREEN.sl[y].current->next,
- CURRENT_SCREEN.sl[y].line_number+1L,direction);
- }
- /*---------------------------------------------------------------------*/
- /* Set flags for bottom_of_screen and bottom_of_file as appropriate. */
- /*---------------------------------------------------------------------*/
- if (*number_focus_rows == 0)
- *limit_of_screen = TRUE;
- if (CURRENT_SCREEN.sl[y].line_type == LINE_TOF_EOF
- && CURRENT_SCREEN.sl[y].current->next == NULL)
- *limit_of_file = TRUE;
- break;
- case DIRECTION_BACKWARD:
- /*---------------------------------------------------------------------*/
- /* Determine the new focus line and the number of rows to adjust the */
- /* cursor position. */
- /*---------------------------------------------------------------------*/
- for (i=CURRENT_SCREEN.rows[WINDOW_MAIN]-1;i>-1;i--)
- {
- if (CURRENT_SCREEN.sl[i].line_number == CURRENT_VIEW->focus_line)
- {
- y = i;
- continue;
- }
- if (CURRENT_SCREEN.sl[i].line_number != (-1L)
- && y != CURRENT_SCREEN.rows[WINDOW_MAIN])
- {
- *number_focus_rows = y-i;
- *new_focus_line = CURRENT_SCREEN.sl[i].line_number;
- break;
- }
- }
- /*---------------------------------------------------------------------*/
- /* If we have NOT set a new focus line (because we are on the top */
- /* of the screen) the new focus line is the prev line in scope (if */
- /* SHADOW is OFF). If SHADOW is ON, the new focus line is determined by*/
- /* the status of the current focus line. */
- /*---------------------------------------------------------------------*/
- if (*new_focus_line == (-1L))
- {
- if (CURRENT_VIEW->shadow)
- {
- if (CURRENT_SCREEN.sl[y].line_type == LINE_SHADOW)
- *new_focus_line = CURRENT_SCREEN.sl[y].line_number - 1L;
- else
- {
- if (CURRENT_SCREEN.sl[y].current->prev != NULL)
- {
- *new_focus_line = find_next_in_scope(CURRENT_SCREEN.sl[y].current->prev,
- CURRENT_SCREEN.sl[y].line_number-1L,direction);
- if (*new_focus_line != CURRENT_SCREEN.sl[y].line_number-1L)
- *new_focus_line++;
- }
- }
- }
- else
- {
- if (CURRENT_SCREEN.sl[y].current->prev != NULL)
- *new_focus_line = find_next_in_scope(CURRENT_SCREEN.sl[y].current->prev,
- CURRENT_SCREEN.sl[y].line_number-1L,direction);
- }
- }
- /*---------------------------------------------------------------------*/
- /* Determine the new current line and the number of rows to adjust the */
- /* cursor position. */
- /*---------------------------------------------------------------------*/
- *leave_cursor = TRUE;
- *new_current_line = (-1L);
- for (i=CURRENT_VIEW->current_row-1;i>-1;i--)
- {
- if (CURRENT_SCREEN.sl[i].line_type == LINE_LINE
- || CURRENT_SCREEN.sl[i].line_type == LINE_TOF_EOF)
- {
- *new_current_line = CURRENT_SCREEN.sl[i].line_number;
- break;
- }
- if (CURRENT_SCREEN.sl[i].line_type == LINE_SHADOW)
- *leave_cursor = FALSE;
- }
- /*---------------------------------------------------------------------*/
- /* If we have NOT set a new current line (only way this can happen is */
- /* if all lines before the current line are RESERVED, SCALE or TABLINE)*/
- /* and the cursor is on the current line) the new current line is the */
- /* previous line in scope. */
- /*---------------------------------------------------------------------*/
- if (*new_current_line == (-1L))
- {
- if (CURRENT_SCREEN.sl[y].current->prev != NULL)
- *new_current_line = find_next_in_scope(CURRENT_SCREEN.sl[y].current->prev,
- CURRENT_SCREEN.sl[y].line_number-1L,direction);
- }
- /*---------------------------------------------------------------------*/
- /* Set flags for top_of_screen and top_of_file as appropriate. */
- /*---------------------------------------------------------------------*/
- if (*number_focus_rows == 0)
- *limit_of_screen = TRUE;
- if (CURRENT_SCREEN.sl[y].line_type == LINE_TOF_EOF
- && CURRENT_SCREEN.sl[y].current->prev == NULL)
- *limit_of_file = TRUE;
- break;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return;
- }
- /***********************************************************************/
- #ifdef PROTO
- short find_last_focus_line(unsigned short *newrow)
- #else
- short find_last_focus_line(newrow)
- unsigned short *newrow;
- #endif
- /***********************************************************************/
- {
- /*------------------------- external data -----------------------------*/
- /*--------------------------- local data ------------------------------*/
- register short i=0;
- short row=(-1);
- short rc=RC_OK;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_last_focus_line");
- #endif
- for (i=CURRENT_SCREEN.rows[WINDOW_MAIN]-1;i>-1;i--)
- {
- if (CURRENT_SCREEN.sl[i].line_number != (-1L))
- {
- *newrow = row = i;
- break;
- }
- }
- if (row == (-1))
- rc = RC_INVALID_OPERAND;
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- short find_first_focus_line(unsigned short *newrow)
- #else
- short find_first_focus_line(newrow)
- unsigned short *newrow;
- #endif
- /***********************************************************************/
- {
- /*------------------------- external data -----------------------------*/
- /*--------------------------- local data ------------------------------*/
- register short i=0;
- short row=(-1);
- short rc=RC_OK;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("target.c: find_first_focus_line");
- #endif
- for (i=0;i<CURRENT_SCREEN.rows[WINDOW_MAIN];i++)
- {
- if (CURRENT_SCREEN.sl[i].line_number != (-1L))
- {
- *newrow = row = i;
- break;
- }
- }
- if (row == (-1))
- rc = RC_INVALID_OPERAND;
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
-